﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FinalTestMachine
{
    public static class GlobalParams
    {
        /// <summary>
        ///  关键参数：终检测试机工站数量
        ///  若要配合使用，还需要做如下工作
        ///  1.在FunSocketSettings手动添加治具开合检测IsUseSocket{n}Sensor 和 治具IsUseSocket{n}，n为A-Z大写，按顺序命名
        ///  2.FunStationSettings中创建对应工位Site1IsUse的启用禁用选项（数字从1到WorkstaionSum）
        ///  3.ProductNumberManager为每一站ok/ng计数添加对应字段
        /// </summary>
        public const int WorkstationSum = 6;

        /// <summary>
        /// 程控电源数量
        /// </summary>
        public const int ProgramablePowerSum = 3;

        /// <summary>
        /// OPT光源控制器数量
        /// </summary>
        public const int OPTSum = 2;

        /// <summary>
        /// opt通道数量
        /// </summary>
        public const int OPTChannelSum = 16;

        #region  读写静态类或对象的字段或属性值
        public static T GetPropertyValue<T>(object obj, string propertyName, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
        {
            if (obj == null)
                throw new ArgumentNullException(nameof(obj));

            if (string.IsNullOrEmpty(propertyName))
                throw new ArgumentNullException(nameof(propertyName));

            Type type = obj.GetType();
            PropertyInfo propertyInfo = type.GetProperty(propertyName, bindingFlags);

            if (propertyInfo == null)
                throw new ArgumentException($"属性 {propertyName} 在类型 {type.Name} 中不存在");

            return (T)propertyInfo.GetValue(obj);
        }

        public static object SetPropertyValue(object obj, string propertyName, object propertyValue, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
        {
            if (obj == null)
                throw new ArgumentNullException(nameof(obj));

            if (string.IsNullOrEmpty(propertyName))
                throw new ArgumentNullException(nameof(propertyName));

            Type type = obj.GetType();
            PropertyInfo propertyInfo = type.GetProperty(propertyName, bindingFlags);

            if (propertyInfo == null)
                throw new ArgumentException($"属性 {propertyName} 在类型 {type.Name} 中不存在");

            propertyInfo.SetValue(obj,propertyValue);
            return true;
        }

        public static T GetFieldValue<T>(object obj, string fieldName, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
        {
            if (obj == null)
                throw new ArgumentNullException(nameof(obj));

            if (string.IsNullOrEmpty(fieldName))
                throw new ArgumentNullException(nameof(fieldName));

            Type type = obj.GetType();
            FieldInfo fieldInfo = type.GetField(fieldName, bindingFlags);

            if (fieldInfo == null)
                throw new ArgumentException($"字段 {fieldName} 在类型 {type.Name} 中不存在");

            return (T)fieldInfo.GetValue(obj);
        }

        public static object SetFieldValue(object obj, string fieldName, object fieldValue, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance)
        {
            if (obj == null)
                throw new ArgumentNullException(nameof(obj));

            if (string.IsNullOrEmpty(fieldName))
                throw new ArgumentNullException(nameof(fieldName));

            Type type = obj.GetType();
            FieldInfo propertyInfo = type.GetField(fieldName, bindingFlags);

            if (propertyInfo == null)
                throw new ArgumentException($"属性 {fieldName} 在类型 {type.Name} 中不存在");

            propertyInfo.SetValue(obj,fieldValue);
            return true;
        }

        public static T GetStaticFieldValue<T>(Type staticType, string fieldName, bool throwIfNotFound = true)
        {
            if (staticType == null)
                throw new ArgumentNullException(nameof(staticType));

            if (string.IsNullOrWhiteSpace(fieldName))
                throw new ArgumentException("Field name cannot be null or empty", nameof(fieldName));

            // 获取字段，包括公共和非公共静态字段
            FieldInfo field = staticType.GetField(fieldName,
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

            if (field == null)
            {
                if (throwIfNotFound)
                    throw new ArgumentException($"Static field '{fieldName}' not found in type {staticType.FullName}");
                return default;
            }

            try
            {
                object value = field.GetValue(null); // 静态字段传入null
                return (T)value;
            }
            catch (InvalidCastException)
            {
                throw new InvalidCastException($"Cannot cast field '{fieldName}' from {field.FieldType} to {typeof(T)}");
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Failed to get value of static field '{fieldName}'", ex);
            }
        }

        public static bool SetStaticFieldValue<T>(Type staticType, string fieldName, object Value , bool throwIfNotFound = true)
        {
            if (staticType == null)
                throw new ArgumentNullException(nameof(staticType));

            if (string.IsNullOrWhiteSpace(fieldName))
                throw new ArgumentException("Field name cannot be null or empty", nameof(fieldName));

            // 获取字段，包括公共和非公共静态字段
            FieldInfo field = staticType.GetField(fieldName,
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

            if (field == null)
            {
                if (throwIfNotFound)
                    throw new ArgumentException($"Static field '{fieldName}' not found in type {staticType.FullName}");
                return default;
            }

            try
            {
                field.SetValue(null,Value); // 静态字段传入null
                return true;
            }
            catch (InvalidCastException)
            {
                throw new InvalidCastException($"Cannot cast field '{fieldName}' from {field.FieldType} to {typeof(T)}");
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Failed to get value of static field '{fieldName}'", ex);
            }
        }
        #endregion
    }
}
